Note: This tutorial is outdated, for the current version see nao/Tutorials/Cross-Compiling. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Cross-Compiling ROS for the Nao (cturtle on NaoQI 1.6)
Description: This tutorial covers the steps necessary for cross-compiling ROS cturtle for the Nao's AMD Geode platform (NaoQI 1.6).Keywords: Nao, Cross-compile
Tutorial Level: INTERMEDIATE
Contents
Introduction
This page explains how to setup ROS to run on the humanoid robot Nao. Note that the steps here haven't been tested on many machines yet. If you try this out for yourself, be kind and take notes of any flaws in this guide and update this page accordingly. This tutorial follows mostly the GumROS tutorial for the compilation of the non-ROS packages.
We are going to cross-compile ROS for the nao platform with a geode CPU. As the geode is x86 CPU this is not definitly necessary for getting ROS running on the Nao - you can just copy binaries from another x86 machine if the dynamically linked libraries are of the same versions. As this is not always the case, cross-compiling is the preferred way. Nao's operating system is stored on a removable USB-stick. We are going to install ROS to the same stick at the path
/media/external/ros
Make sure that you have enough space left on the stick. In our lab, we replaced the original 2GB USB stick with an 8 GB USB stick by Transcend. I will only explain how to compile the ROS base system, which should also fit onto the original stick. If you want to store ROS to a different path, make appropriate adjustments to the instructions below. Make sure that this path exists on your build machine and that you own the appropriate directory with all its subdirectories, otherwise you could encounter errors during installation. Once ROS is installed, you cannot move it unless you recompile it, because the paths to libraries are stored in the binaries.
Requirements
You need Aldebaran's Nao SDK (SDK), at least version 1.6.0 and Aldebaran's Cross-Compile-Toolkit (CTC), at least version 1.6.0. Aldebaran provides a toolchain for cross-compiling cmake based projects for the Nao platform. This comes very handy when cross-compiling ROS, as it is also cmake-based. However, ROS depends on a few libraries which we need to build before we can start with the actual cross-compilation of ROS. These libraries however use automake, hence the cmake toolchain provided by Aldebaran is not applicable. Instead, we need to set some environment variables used by automake. You can save the following commands to a shell script, adjust it according to your setup and execute it.
# some basic settings export TARGETDIR=/media/external #this is where ROS will be installed to, see below export ROS_ROOT=$TARGETDIR/ros/ros # ROS_ROOT, as usual export ROS_PACKAGE_PATH=$ROS_ROOT/../stacks # ROS_PACKAGE_PATH, as usual export CTC_DIR=/path/to/ctc-academics-1.6.13 # path to Aldebaran's cross-compilation toolchain export ROS_DEPS=$ROS_ROOT/../ros-deps/ export CTC_USR_DIR=$CTC_DIR/staging/geode-linux/usr/ export CTC_BIN_DIR=$CTC_DIR/cross/geode/bin export PYTHONPATH=$ROS_ROOT/core/roslib/src export CPATH=$ROS_ROOT/../ros-deps/include/ export GEODE_CXX=$CTC_DIR/cross/geode/bin/i586-linux-g++ export GEODE_CC=$CTC_DIR/cross/geode/bin/i586-linux-gcc export PATH=$CTC_BIN_DIR:$ROS_ROOT/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin export LD_LIBRARY_PATH=. # automake compiler/linker flags export LDFLAGS="-Wl,--sysroot,$CTC_DIR/staging/geode-linux/ -lgcc -L$CTC_DIR/cross/geode/i586-linux/lib/ -L$CTC_DIR/staging/geode-linux/usr/lib -lc -lstdc++ -ldl" export CPPFLAGS="--sysroot /$CTC_DIR/staging/geode-linux/ -I/$CTC_DIR/staging/geode-linux/usr/include/ -I/$CTC_DIR/cross/geode/lib/gcc/i586-linux/4.3.3/include/ -I/$CTC_DIR/staging/geode-linux/usr/include/c++/ -I/$CTC_DIR/staging/geode-linux/usr/include/c++/i586-linux/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/backward/ -I/$CTC_DIR/cross/geode/i586-linux/include/c++/i586-linux -I/$CTC_DIR/cross/geode/i586-linux/include/ -I/$CTC_DIR/staging/geode-linux/usr/lib" export CFLAGS="-march=geode" export CXXFLAGS="-march=geode"
Cross-Compiling of non-ROS modules
Download them to whatever location you want but you need to use the environment setup from above and sepcify the right prefix path. This is where the packages will end up.
First, we build apr.
wget http://www.powertech.no/apache/dist/apr/apr-1.4.2.tar.bz2 extract the package and cd into the new directory ./configure --prefix=$ROS_DEPS --disable-shared --enable-static CC=$GEODE_CC --host=i586-linux make && make install cd ..
Next we compile apr-utils
wget http://www.powertech.no/apache/dist/apr/apr-util-1.3.10.tar.bz2 extract the package and cd into the new directory ./configure --prefix=$ROS_DEPS --with-apr=$ROS_DEPS/apr-1.4.2 --with-expat=builtin CC=$GEODE_CC --host=i586-linux --without-pgsql --without-sqlite2 --without-sqlite3 \ ac_cv_file__dev_zero=yes \ ac_cv_func_setpgrp_void=yes \ apr_cv_tcp_nodelay_with_cork=no \ apr_cv_process_shared_works=no \ apr_cv_mutex_robust_shared=no \ ac_cv_sizeof_struct_iovec=8 make && make install cd ..
If you experience errors like
ctc-academics-1.6.13/cross/geode/bin/../lib/gcc/i586-linux/4.3.3/../../../../i586-linux/bin/ld: crti.o: No such file: No such file or directory
during compilation of expat (part of apr-util) you are probably best off creating the directory
/home/opennao/opennao-1-4-x/build/tmp/
and copy all files from the ctc directory into that directory, i.e.,
cp -r $CTC_DIR/* /home/opennao/opennao-1-4-x/build/tmp/
I know this is ugly, but I could not find a proper solution. If you know one, give me a hint!
Finally, we can compile log4cxx
wget http://pr.willowgarage.com/downloads/apache-log4cxx-0.10.0-wg_patched.tar.gz extract the package and cd into the new directory ./configure --prefix=$ROS_DEPS --with-apr=$ROS_DEPS --with-apr-util=$ROS_DEPS CC=$GEODE_CC CXX=$GEODE_CXX LDFLAGS="$LDFLAGS" --host=i586-linux \ ac_cv_file__dev_zero=yes \ ac_cv_func_setpgrp_void=yes \ apr_cv_tcp_nodelay_with_cork=no \ apr_cv_process_shared_works=no \ apr_cv_mutex_robust_shared=no \ ac_cv_sizeof_struct_iovec=8 make && make install
If you experience the error message
/bin/sed: can't read /usr/lib/libiconv.la: No such file or directory
it might be necessary to edit
$ROS_DEPS/lib/libaprutil-1.la
and look for libiconv.la and change the path from
/usr/bin/libiconv.la to $CTC_USR_DIR/lib/libiconv.la
If you experience the error message
i586-linux-g++: crti.o: No such file or directory i586-linux-g++: crtn.o: No such file or directory
edit the file
libtool
and search for crti.o and crtn.o and append the full path to those files, i.e. point it to $CTC_USR_DIR/lib/ .
If you experience errors like
undefined reference to `cerr'
while building the examples, you might need to
edit src/examples/cpp/console.cpp to include <stdio.h>
In $TARGETIDR/ros-deps/lib, you should now have libapr-1.*, libaprutil-1.* libexpat.*, and liblog4cxx.*
Cross-Compiling ROS
Once all this is complete, we can start to build ROS.
First, get rosinstall and the appropriate .rosinstall file
cd $TARGETDIR wget http://www.ros.org/rosinstall wget http://ros.org/rosinstalls/cturtle_base.rosinstall
Then start to download packages using rosinstall
chmod +x rosinstall ./rosinstall -n ros cturtle_base.rosinstall
Now setup the toolchain to include Aldebaran's cmake toolchain file
echo "include(\"$CTC_DIR/toolchain-geode.cmake\")" >> ros/ros/rostoolchain.cmake echo "include_directories(\"$TARGETDIR/ros/ros-deps/include\")" >> ros/ros/rostoolchain.cmake echo "link_directories(\"$TARGETDIR/ros/ros-deps/lib\")" >> ros/ros/rostoolchain.cmake
rxtools needs wxwidgets which is not available for the Nao so we do not build it
touch ros/ros/tools/rxtools/ROS_NOBUILD
Afterwards, get rid of all the automake flags, otherwise cmake gets all crazy
export CFLAGS= export CXXFLAGS= export CPPFLAGS= export LDFLAGS= export CPATH= export PATH=$TARGETDIR/ros/ros/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
We can then start to build a base system of ros
cd ros/ros && make cd .. rosmake ros # just to be sure...
Installing TF
TF does not cross-compile out of the box, I needed to patch the CMakeList.txt and Makefile for bullet and TF.
Download tf_patches.tgz and point a variable to the directory containing the extracted files
export PATCHESDIR= #path to extracted tf_patches.tgz
Then we need to apply the patches and call rosmake to compile TF
roscd bullet && patch < $PATCHESDIR/Makefile.bullet.patch roscd tf && patch < $PATCHESDIR/tf.CMakeLists.txt.patch && cd $TARGETDIR rosmake tf
Also, we need to copy some boost libraries from the CTC directory which are missing on the Nao's USB stick
cd $TARGETDIR mkdir libs cp -r $CTC_USR_DIR/lib/libboost* $TARGETDIR/libs/ echo "export LD_LIBRARY_PATH=$TARGETDIR/libs:\$LD_LIBRARY_PATH" >> $TARGETDIR/ros/setup.sh
Finally, we need to copy the python yaml and xmlrpc packages from the host system (need to be installed on the host system first of course)
mkdir python cp -r /usr/lib/python2.6/dist-packages/yaml $TARGETDIR/python/ cp /usr/lib/python2.6/SimpleXMLRPCServer* $TARGETDIR/python/ cp /usr/lib/python2.6/xmlrpclib* $TARGETDIR/python/ echo "export PYTHONPATH=\$PYTHONPATH:$TARGETDIR/python" >> $TARGETDIR/ros/setup.sh
Again, if you know a better way to do this, let me know!
Further Packages
So far, the following packages should compile and run on the Nao:
rosmake hokuyo_node rosmake common rosmake geometry rosmake driver_common
Currently, the following packages are not compiling:
rosmake camera_drivers rosmake navigation
These packages probably either have faulty CMakeList.txt files or depend on a some other package with broken CMakeFiles. I never needed those packages, so I did not look into it.
Installation
Just copy the directory
/media/external
to the same path on the Nao's USB stick. Log onto the robot, bring up a bash and call
/media/external/ros/setup.sh
and ROS should be running (until you log out).
Final Remark
If you know how to fix one or more of the issues I came across, please let me (Daniel Maier) know so I can update this page. Your contribution will be mentioned of course